#!/usr/bin/python
# -*- coding: utf-8 -*-

#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

import time
import socket
import dictclient
import sddpy


valid_symbols=set(' !"#$%&\'()*+,-./0123456789:;<=>?@[\\]^_`{|}~')
def str_filter(string):
    return filter(lambda c: c.isalpha() or c in valid_symbols, string)

class Error(Exception):
    """Base error class"""
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return repr(self.value)

class ConnectionError(Error):
    pass

class ProtocolError(Error):
    pass

class Dictionaries(dict):
    def __init__(self, dicts, aliases={}, descriptions={},
                 simple_naming=False):
        dict.__init__(self)
        for id in dicts:
            DRL=dicts[id]
            print DRL
            protocol, address = DRL.split('://',1)
            if protocol == 'dictd':
                dictd = dictclient.Connection(address)
                dbs = dictd.getdbdescs()
                for db in dbs.keys():
                    full_name = db + '@' + id
                    self[full_name]=DictdDictionary(db, address, dbs[db])
            elif protocol == 'stardict':
                stardict = sddpy.Dicts(address)
                for db in stardict:
                    full_name = db.name + '@' + id
                    db.__class__ = StardictDictionary
                    self[full_name] = db
                    #print self[full_name].dsc
            else:
                raise ProtocolError('Unknown protocol %s.' % protocol)
        for did in self.keys():
            if aliases.has_key(did):
                self[aliases[did]]=self[did]
                del(self[did])
            elif simple_naming:
                alias=did.split('@',1)[0]
                self[alias]=self[did]
                del(self[did])
        for did in self.keys():
            #print did
            #print descriptions
            if descriptions.has_key(did):
                print did
                self[did].dsc = descriptions[did]

class DictdDictionary(object):
    """This class stores parametrs for a dictionary"""
    def __init__(self, database, server, dsc=''):
        """The url for dictd protocol is database@server"""
        self.db = database
        self.server = server
        self.dsc = dsc

    def translate(self, word):
        """Translate a word using currend dictionary"""
        word = str_filter(word)
        try:
                dictd = dictclient.Connection(self.server)
        except socket.error:
            raise ConnectionError('Error connecting to server %s.' %
                                  self.server)
        definations = dictd.define(self.db, str_filter(word).encode('UTF8'))
        reply = ''
        for defination in definations:
            reply += defination.getdefstr()
        if reply == '':
            reply = None
        return reply


class StardictDictionary(sddpy.Dict):
    dsc = ''

    def translate(self, word):
        try:
            return self.lookup(word)
        except sddpy.LookupError:
            return None
